/**
*  \file grits.c
*
*  \brief
*
*  \author   <@linde-mh.de>
*
*
*/

/*===============================================[ private includes  ]================================================*/
#include "grits.h"
#include <stddef.h>
/*===============================================[ private defines   ]================================================*/

/*===============================================[ private datatypes ]================================================*/

/*===============================================[ private variables ]================================================*/

/*===============================================[ public variables  ]================================================*/

/*===============================================[ private functions ]================================================*/
static struct tasklet * grits_tasklet_run( struct tasklet_list *list,struct tasklet *cursor   );
/*====================================================================================================================*/


/**
*  Initialization.
*
*  Initialize the grits module.
*
*  \return RC_SUCCESS if successful.
*/
RC grits_initialize( struct grits_time_slice *sched, U32 size, U32 ticks  )
{
	while( size-- ) /* for number of structs in sched */
	{
		tasklet_list_initialize( &sched->list, NULL );
		sched->next_run_time = ticks;
		sched++;
	}
	return RC_SUCCESS;
}


void grits_process_time( struct grits_time_slice *sched, U32 size, U32 ticks )
{
	while( size-- ) /* for number of structs in sched */
	{
		if( sched->next_run_time <=ticks   ) /*if task */
		{
			sched->cursor = grits_tasklet_run( &sched->list, sched->cursor );
			if( NULL == sched->cursor )
			{
				sched->next_run_time += sched->interval;
			}
			return ;
		}
		sched++;
	}
}


struct tasklet * grits_tasklet_run( struct tasklet_list *list,struct tasklet *cursor   )
{
	ASSERTOR_PRE( NULL != list, "Parameter list can't be NULL."  );

	if( NULL == cursor )
	{
		cursor = LIST_FIRST( &list->tasklet_list);
	}
      if( NULL != cursor )
      {
         struct tasklet* next=LIST_NEXT( cursor );
         /* remember next element. This is imporatant if item will be unlinked in the next function call. */

         U32 tasklet_time = list->timer_function();

         LIST_DATA(cursor)->function(cursor);

         tasklet_time = list->timer_function() - tasklet_time;

         if( tasklet_time > LIST_DATA(cursor)->tasklet_time )
         {
            LIST_DATA(cursor)->tasklet_time = tasklet_time;
         }
         cursor = next;
      }

	return cursor;
}

/***********************************************************************************************************************
*                             Copyright 2015 Linde Material Handling. All rights reserved.                             *
***********************************************************************************************************************/
